home *** CD-ROM | disk | FTP | other *** search
/ Programming Sound Cards / Programming Sound Cards.iso / sound_45 / mod_dis.c < prev    next >
C/C++ Source or Header  |  1995-01-01  |  33KB  |  1,127 lines

  1. /* BEGIN DAVID LAI COPYRIGHT ********************************************* */
  2. /*
  3. (C) Copyright David Lai 1993, 1994.  All rights reserved.
  4.  
  5. The source code is copyright by David Lai, however it is freely
  6. distributable and released for unrestricted use.  Users may copy or modify 
  7. this source code without charge, provided all copyright
  8. notices remain intact in all the source code.  Portions of the source code
  9. copyright by their respective copyright holders and are covered
  10. under different agreements, however the source code used has
  11. specifically been marked distributable royalty-free.
  12.  
  13. You can do whatever you want with it, even charge money for it, if
  14. you find a sucker willing to pay for it.  This is not shareware, the program
  15. is not crippled in any way, do not send money.  You can e-mail comments
  16. to the electronic mail address below, or fax to the fax number below.
  17.  
  18. If you add a feature thats useful, or do a new port, you can send
  19. the context diffs to the e-mail address below.  I may include it in
  20. subsequent releases.  Your code must specifically be marked
  21. freely distributable, I will not include code marked otherwise.
  22.  
  23. THE SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
  24. THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  25. PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  26.  
  27. The source code is provided with no support and without any obligation on
  28. the part of David Lai to assist in its use, correction,
  29. modification or enhancement.
  30.  
  31. DAVID LAI SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  32. INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
  33. OR ANY PART THEREOF.
  34.  
  35. In no event will David Lai be liable for any lost revenue
  36. or profits or other special, indirect and consequential damages, even if
  37. David Lai has been advised of the possibility of such damages.
  38.  
  39. David Lai
  40. 1370 McKendrie St
  41. San Jose, CA 95126
  42. fax: 408-241-4615
  43.  
  44. lai%fastfood@daver.bungi.com
  45.  
  46. */
  47. /* END   DAVID LAI COPYRIGHT ********************************************* */
  48.  
  49. /* dis-assemble a mod file */
  50.  
  51. #include "misc.h"
  52. #include "modcomp.h"
  53. #include "wav.h"
  54.  
  55. #include "mod_disv.c"    /* some initialized arrays */
  56.  
  57. /* ALLOW_CONTROLS will allow control characters and non-printing characters
  58.    in the name of the mod */
  59. #undef ALLOW_CONTROLS
  60.  
  61. /* RPT_LENGTH_IS_INCR interprets the rpt_length field of samples as 1 more
  62.    than the actual number of words to repeat, for example:
  63.  
  64.     length = 500
  65.     rpt_offset = 0
  66.     rpt_length = 500
  67.  
  68.    The user really meant to say:
  69.  
  70.     length = 500 (998 bytes of real sample)
  71.     rpt_offset = 0 (begin the repeat at the first byte of the real sample)
  72.     rpt_length = 499 (repeat entire 998 bytes of the sample)
  73.  
  74.    Without RPT_LENGTH_IS_INCR, the above will generate warning message that
  75.    there is an attempt to repeat beyond the end of the sample (1000 bytes)
  76. */
  77. #define RPT_LENGTH_IS_INCR
  78.  
  79. static struct sample samples[MAX_INSTRUMENTS];
  80. static int channels=0, instruments=0, num_patterns;
  81. static char mod_tag[MOD_TAGSIZE+1]="";
  82. static char mod_name[MOD_NAME_LENGTH+1];
  83. static int verbose=0;
  84. static int adj, tagsize=MOD_TAGSIZE;
  85. static unsigned char num_patterns_in_song, end_jump_pos;
  86. static unsigned char pattern_table[PATTERN_TABLE_SIZE];
  87. static uint32 file_size;
  88. static int pattern_size;
  89. static off_t fixed_size;
  90. static char *mod_format="mod";
  91. static int file_has_gaps=0;
  92. static int dump_unused_patterns=0;
  93. static uint32 wav_sample_rate=16574;    /* .wav sample rate */
  94.             /* initially set to the middle C rate */
  95. static int wav_info_flag = 1;    /* dump INFO unless requested not to */
  96.  
  97. #define PATTERN_SPACE ((uint32)num_patterns * pattern_size)
  98.  
  99. #ifdef __STDC__
  100. read_tag0(FILE *fi, off_t offset, char tag[MOD_TAGSIZE+1])
  101. #else
  102. read_tag0(fi, offset, tag) FILE *fi; off_t offset; char tag[MOD_TAGSIZE+1];
  103. #endif
  104.  {
  105.  /* read the 4 byte tag at the offset specified and attempt to interpret */
  106.  if (fseek(fi, offset, SEEK_SET)!=0)
  107.     err_exit("Badly formed MOD file: cant seek to tag", NULL);
  108.  if (fread(tag, sizeof(char), MOD_TAGSIZE, fi) != MOD_TAGSIZE)
  109.     err_exit("Badly formed MOD file: cant read tag",NULL);
  110.  tag[MOD_TAGSIZE]='\0';
  111.  if (strcmp(tag,"M.K.")==0 || strcmp(tag,"FLT4")==0 || strcmp(tag,"M!K!")==0 ||
  112.     strcmp(tag,"4CHN")==0 || strcmp(tag,"M&K!")==0 )
  113.     {
  114.     channels = 4;
  115.     return 1; /* success */
  116.     }
  117.  else if (strcmp(tag,"6CHN")==0)
  118.     {
  119.     channels = 6;
  120.     return 1; /* success */
  121.     }
  122.  else if (strcmp(tag,"8CHN")==0 || strcmp(tag,"OCTA")==0)
  123.     {
  124.     channels = 8;
  125.     return 1; /* success */
  126.     }
  127.  else
  128.     return 0; /* dont know this tag */
  129.  }
  130.  
  131. #ifdef __STDC__
  132. read_tag(FILE *fi)
  133. #else
  134. read_tag(fi) FILE *fi;
  135. #endif
  136.  {
  137.  /* read and interpret tag to determine file format */
  138.  char tag[MOD_TAGSIZE+1], tag15[MOD_TAGSIZE+1];
  139.  /* check if it is a 31 instr file first */
  140.  if (read_tag0(fi, TAG_OFFSET_31, tag)==1)
  141.   {
  142.   instruments = 31;
  143.   strcpy(mod_tag, tag);
  144.   return 1;
  145.   }
  146.  /* try again with 15 instr */
  147.  if (read_tag0(fi, TAG_OFFSET_15, tag15)==1)
  148.   {
  149.   instruments = 15;
  150.   strcpy(mod_tag, tag15);
  151.   return 1;
  152.   }
  153.  /* take a guess that it is 4 track */
  154.     if (verbose) fprintf(stderr, "Warning: Unknown tag 31=%s 15=%s\n", tag, tag15);
  155.     fprintf(stderr,"Unknown mod format - assuming -c 4 -i 15\n");
  156.     channels = 4;
  157.     instruments = 15;
  158.     tagsize = 0;
  159. #if 0
  160.     {
  161.     int c;
  162.     /* check if there is printable chars at location 470 */
  163.     if (fseek(fi, CHECK_31_INST_OFFSET, SEEK_SET)!=0)
  164.         err_exit("Unable to seek to check", NULL);
  165.     c=getc(fi);
  166.     if (isascii(c) && isprint(c))    /* this test may not work all the time */
  167.         {
  168.         instruments = 31;
  169.           strcpy(mod_tag, tag15);
  170.         }
  171.     else
  172.         {
  173.         instruments= 15;
  174.           strcpy(mod_tag, tag15);
  175.         }
  176.     }
  177. #endif
  178.  return 1;
  179.  }
  180.  
  181. void
  182. #ifdef __STDC__
  183. verify_format(FILE *fi)
  184. #else
  185. verify_format(fi) FILE *fi;
  186. #endif
  187.  {
  188.  /* verify the name of the mod is valid */
  189.  int i,j;
  190.  uint32 total_sample_size;
  191.  if (fseek(fi, 0L, SEEK_SET)!=0)
  192.     err_exit("Badly formed MOD file", NULL);
  193.  if(fread(mod_name, sizeof(char), MOD_NAME_LENGTH, fi) != MOD_NAME_LENGTH)
  194.     err_exit("Badly formed MOD file - mod name", NULL);
  195.  mod_name[MOD_NAME_LENGTH]='\0';
  196.  /* check all chars are valid */
  197.  for (i=0; i< MOD_NAME_LENGTH; i++) 
  198.     if ((!isascii(mod_name[i])) || (!isprint(mod_name[i]) && mod_name[i]!='\0'))
  199. #ifndef ALLOW_CONTROLS
  200.         err_exit("Bad mod name, character 0x%x",(unsigned char)mod_name[i]);
  201. #else
  202.         fprintf(stderr, "Bad mod name, character 0x%x\n",(unsigned char)mod_name[i]);
  203. #endif
  204.  /* verify that all sample headers are OK */
  205.  for (j=0; j< instruments; j++)
  206.     {
  207.      if (fseek(fi, SAMPLE_HEADER_OFFSET + 
  208.         SAMPLE_HEADER_LENGTH *j, SEEK_SET)!=0)
  209.         err_exit("Badly formed MOD file, cant read sample headers", NULL);
  210.      if (fread( samples[j].name, sizeof(char), SAMPLE_NAME_SIZE, fi) != 
  211.         SAMPLE_NAME_SIZE)
  212.             err_exit("Cant read sample name %d",j);
  213.     samples[j].name[SAMPLE_NAME_SIZE]='\0';
  214.     if (verbose > 1)
  215.      {
  216.      for(i=0; samples[j].name[i]!='\0' && i< SAMPLE_NAME_SIZE; i++)
  217.         if (!isprint(samples[j].name[i]) && isascii(samples[j].name[i]))
  218.             fprintf(stderr,"Warning: Bad character in sample #%d name, character 0x%x in %s\n",
  219.               j, (unsigned char)samples[j].name[i], samples[j].name);
  220.      }
  221.     samples[j].length = rbshort(fi);
  222.     samples[j].orig_length = samples[j].length;
  223.     if (samples[j].length == (SAMPLE_IGNORE_BYTES / 2)) 
  224.         {
  225.         if (verbose > 1) 
  226.             fprintf(stderr,"Warning: zeroing sample %d length (was %u)\n",
  227.              j,samples[j].length);
  228.         samples[j].length = 0;
  229.         adj+= (SAMPLE_IGNORE_BYTES / 2); 
  230.              /* adjustment for filelength checks */
  231.         }
  232.     if (fread( &samples[j].finetune, 1, 1, fi)!=1)
  233.         err_exit("Cant read sample %d's finetune", j);
  234.     /* sign extend finetune */
  235.     samples[j].finetune = SIGN_EXT_NIBBLE(samples[j].finetune);
  236.     if (fread( &samples[j].volume, 1, 1, fi)!=1)
  237.         err_exit("Cant read sample %d's volume", j);
  238.     if (samples[j].volume > 64)
  239.         {
  240.         if (verbose)
  241.             fprintf(stderr,"Warning: volume for sample %d out of range %d, set to 64\n",j, samples[j].volume);
  242.         samples[j].volume = 64;
  243.         }
  244.     samples[j].rpt_offset = rbshort(fi);
  245.     samples[j].rpt_length = rbshort(fi);
  246.        if (samples[j].length)
  247.     {
  248. #ifdef RPT_LENGTH_IS_INCR
  249.     /* we assume rpt_length is actually 1 more than the actual # of
  250.        words to repeat, probably represents the AMIGA word */
  251.     if (verbose>1 && samples[j].rpt_length==0)
  252.         fprintf(stderr,"rpt_length==0 in sample %d\n",j);
  253.     if (samples[j].rpt_length && samples[j].rpt_length==(samples[j].length-samples[j].rpt_offset-1))
  254.       {
  255.       if (verbose)
  256.         fprintf(stderr,"LAI length+offset+1=length in sample %d\n",j);
  257.       }
  258.     else if (samples[j].rpt_length) samples[j].rpt_length--;
  259. #else
  260.     /* rpt_length of 1 is interpreted as 0 - this has the unfortunate
  261.        side-effect
  262.        that you cant repeat a loop of 2 bytes (probably wont sound too
  263.        good anyways).  There are just too many mods that set 
  264.        rpt_length to 1 when they really mean 0. */
  265.     if (samples[j].rpt_length==1)
  266.         {
  267.         if (verbose > 1)
  268.           fprintf(stderr,"Warning: rpt_length for sample %d zeroed\n",
  269.             j);
  270.         samples[j].rpt_length=0;
  271.         }
  272. #endif
  273.     /* we use >= below because we assume the rpt_offset is an offset into
  274.        the real data (without the dummy amiga word) */
  275.     if (samples[j].rpt_offset >= samples[j].length)
  276.         {
  277.         if (verbose)
  278.             fprintf(stderr,"Warning: rpt_offset for sample %d out of range %lu (words), looping turned off\n",j, (unsigned long)samples[j].rpt_offset);
  279.         samples[j].rpt_offset = samples[j].length;
  280.         samples[j].rpt_length = 0;
  281.         }
  282.     if (samples[j].rpt_length !=0 &&
  283.         (unsigned long) samples[j].rpt_offset+samples[j].rpt_length >= samples[j].length)
  284.         {
  285. #ifdef RPT_LENGTH_IS_INCR
  286.         if (verbose)
  287. #else
  288.         if (verbose>1 || 
  289.             (((unsigned long)samples[j].length-samples[j].rpt_offset != (unsigned long)samples[j].rpt_length ) 
  290.             && verbose))
  291. #endif
  292.             fprintf(stderr,"Warning: rpt_length for sample %d out of range %lu, set to %lu (words)\n",
  293.              j, (unsigned long)samples[j].rpt_length, 
  294.              (unsigned long)samples[j].length-samples[j].rpt_offset-1);
  295.         samples[j].rpt_length = samples[j].length-samples[j].rpt_offset-1;
  296.         }
  297.     } /* if length!=0 */
  298.     }
  299.  /* verify that patterns header is OK */
  300.  if (fseek(fi, SAMPLE_HEADER_OFFSET + SAMPLE_HEADER_LENGTH * instruments,
  301.     SEEK_SET)!=0)
  302.      err_exit("Badly formed MOD file, cant reach pattern info",NULL);
  303.  if (fread( &num_patterns_in_song, 1, 1, fi)!=1)
  304.         err_exit("Cant read num_patterns_in_song",NULL);
  305.  if (num_patterns_in_song==0 || num_patterns_in_song > 128)
  306.     err_exit("Badly formed MOD file, num_patterns_in_song==%d",num_patterns_in_song);
  307.  if (fread( &end_jump_pos, 1, 1, fi)!=1)
  308.     err_exit("Cant read end_jump_pos",NULL);
  309.  if (end_jump_pos <= MAX_VALID_END_JUMP_POS && end_jump_pos >= num_patterns_in_song)
  310.     {
  311.     /* end_jump_pos==120 is used by some trackers to indicate no looping,
  312.        this should really be set to 127 or some other value>128.  Too
  313.        bad for compatibility the end_jump_pos is in the valid range
  314.        for pattern positions (1-128) when it indicates no looping.  Since
  315.        the ==120 case is so common, we will only issue a diagnostic when
  316.        verbose is set high.
  317.     */
  318.     if (verbose>1 || ( verbose && end_jump_pos!=120))
  319.         fprintf(stderr, "Warning: end_jump_pos out of range %d, looping  disabled\n", end_jump_pos);
  320.     end_jump_pos = MAX_VALID_END_JUMP_POS+1;
  321.     }
  322.  /* verify that all patterns are OK */
  323.  if (fread( pattern_table, sizeof(pattern_table[0]), PATTERN_TABLE_SIZE, fi) != 
  324.     PATTERN_TABLE_SIZE)
  325.         err_exit("Cant read pattern table",NULL);
  326.  /* calculate the total # of patterns stored in the file, we do this by
  327.     subtracting from the file size the fixed portion of the file, and all
  328.     the sample sizes, and dividing by the pattern size */
  329.  pattern_size = NOTESIZE * channels * LINES_PER_PATTERN;
  330.  fixed_size=SAMPLE_HEADER_OFFSET + SAMPLE_HEADER_LENGTH * instruments + 2 +
  331.     sizeof(pattern_table) + tagsize;
  332.  for (j=0, total_sample_size=0; j< instruments; j++)
  333.     {
  334.     total_sample_size += (unsigned long)samples[j].length * 2;
  335.     }
  336.  if (file_size-fixed_size < total_sample_size)
  337.     err_exit("Badly formed MOD file: file too short",NULL);
  338.  num_patterns=(int)((file_size-fixed_size-total_sample_size) / pattern_size);
  339.  if (num_patterns <1 || num_patterns > 256)
  340.     err_exit("Badly formed MOD file: num_patterns==%d",num_patterns);
  341.  if ((PATTERN_SPACE + fixed_size+total_sample_size != file_size)
  342.   && (PATTERN_SPACE + fixed_size+total_sample_size + adj*2 != file_size))
  343.     {
  344.     if (verbose)
  345.      fprintf(stderr,"Warning: excess data in file, %ld bytes\n",
  346.       file_size - (PATTERN_SPACE + fixed_size+
  347.        total_sample_size));
  348.     /* if the excess data is within 4 bytes of the pattern size,
  349.        truncate the last sample and assume there is 1 more
  350.        pattern */
  351.     if ((int)(file_size - (PATTERN_SPACE + fixed_size+total_sample_size)) >=
  352.         pattern_size - 4 )
  353.       {
  354.       int trunc, last_inst;
  355.       trunc = pattern_size - (int)(file_size - (PATTERN_SPACE + fixed_size+total_sample_size));
  356.       if (trunc%2 ==0)
  357.         { /* must be even number */
  358.           /* find last "real" instrument */
  359.           for (j=0,last_inst=0; j< instruments; j++)
  360.            {
  361.            if (samples[j].length!=0) last_inst=j;
  362.            }
  363.           samples[last_inst].length -= trunc/2;
  364.           samples[last_inst].orig_length -= trunc/2;
  365.         /* need to truncate rpt_length only if it loops to end of
  366.            sample */
  367.         if (samples[last_inst].rpt_length + samples[last_inst].rpt_offset >= samples[last_inst].length)
  368.          {
  369.          int max_rpt = samples[last_inst].length - samples[last_inst].rpt_offset - 1;
  370.          if (max_rpt < 1)
  371.           {
  372.           samples[last_inst].rpt_length = 0; /* too short */
  373.           samples[last_inst].rpt_offset = 0;
  374.           }
  375.          else
  376.           {
  377.           samples[last_inst].rpt_length = max_rpt;
  378.           }
  379.          }
  380.           num_patterns++;
  381.         total_sample_size -= trunc;
  382.         if (verbose)
  383.              fprintf(stderr,"Warning: truncating last sample (#%d) by %d bytes to fix size\n", last_inst, trunc);
  384.         }
  385.       }
  386.     }
  387.  /* we will assume that if the file size matches the adjusted size, then there
  388.     are real gaps in the samples.  Probably caused by poorly written
  389.     software which inserts a couple of bytes for empty samples */
  390.  if (adj!=0 && PATTERN_SPACE +fixed_size+total_sample_size+ adj*2 == file_size)
  391.     file_has_gaps = 1;
  392.  else
  393.     file_has_gaps = 0;
  394.  /* verify all pattern indexes in pattern_table are valid */
  395.  for(i=0; i<PATTERN_TABLE_SIZE; i++)
  396.     {
  397.     if (pattern_table[i]>=num_patterns)
  398.         err_exit("Illegal pattern number %d",pattern_table[i]);
  399.     }
  400.  }            
  401.  
  402. void
  403. #ifdef __STDC__
  404. assign_filenames(char *prefix, char *suffix)
  405. #else
  406. assign_filenames(prefix, suffix) char *prefix; char *suffix;
  407. #endif
  408.  {
  409.  int j;
  410.  char namebuf[256];
  411.  for (j=0; j< instruments; j++)
  412.     {
  413.     if (samples[j].length != 0) 
  414.         {
  415.         sprintf(namebuf, "%s%d%s", prefix?prefix:"inst", j,
  416.             suffix?suffix:"");
  417.         if ((samples[j].sample_filename=malloc(strlen(namebuf)+1))==NULL)
  418.             {
  419.             err_exit("Out of Memory", NULL);
  420.             }
  421.         strcpy(samples[j].sample_filename, namebuf);
  422.         }
  423.     }
  424.  }
  425.  
  426. #ifdef __STDC__
  427. void write_headers(char *path)
  428. #else
  429. void write_headers(path) char *path;
  430. #endif
  431.  {
  432.  if (verbose) printf("// Name of File\n");
  433.  printf("mod_filename %s\n",path);
  434.  if (verbose) printf("// Name of Song\n");
  435.  printf("mod_name %s\n",mod_name);
  436.  if (tagsize) 
  437.   {
  438.   if (verbose) printf("// Tag\n");
  439.   printf("mod_tag %s\n",mod_tag);
  440.   }
  441.  if (verbose) printf("// Format\n");
  442.  printf("format %s\n",mod_format);
  443.  if (verbose) printf("// Number of instruments (samples), and channels (voices, tracks)\n");
  444.  printf("instruments %d  channels %d\n", instruments, channels);
  445.  }
  446.  
  447. void
  448. #ifdef __STDC__
  449. write_sample_headers(enum sample_format sample_format)
  450. #else
  451. write_sample_headers(sample_format) enum sample_format sample_format;
  452. #endif
  453.  {
  454.  int j;
  455.  for (j=0; j< instruments; j++)
  456.   {
  457.   if (samples[j].length != 0 || strlen(samples[j].name)!=0) 
  458.     {
  459.     if (verbose) printf("\n// Sample # %d, bytes: %lu\n", j, 
  460.         (samples[j].length!=0)? 
  461.           (unsigned long) samples[j].length * 2 - SAMPLE_IGNORE_BYTES:
  462. #ifdef NO_CONSTANT_SUFFIX
  463.           0);
  464. #else
  465.           0UL);
  466. #endif
  467.     printf("assume sample_number %d\n", j);
  468.     printf(" sample_name %s\n", samples[j].name);
  469.     if( samples[j].length != 0)
  470.      {
  471.     if (samples[j].finetune != 0) printf(" sample_finetune %d\n",samples[j].finetune);
  472.     if (samples[j].volume!= 64) printf(" sample_volume %d\n", samples[j].volume);
  473.     if (samples[j].rpt_length != 0)
  474.         {
  475.         printf(" repeat_offset %lu repeat_length %lu\n",
  476.             (unsigned long)samples[j].rpt_offset* 2, 
  477.             (unsigned long)samples[j].rpt_length*2);
  478.         }
  479.     if (sample_format_table[sample_format].name)
  480.         printf(" sample_format %s\n", sample_format_table[sample_format].name);
  481.     if (samples[j].sample_filename)
  482.         printf(" sample_filename %s\n", samples[j].sample_filename);
  483.      }
  484.     }
  485.   }
  486.  }
  487.  
  488. void
  489. #ifdef __STDC__
  490. write_pattern_header(void)
  491. #else
  492. write_pattern_header()
  493. #endif
  494.  {
  495.  int i, j;
  496.  if (verbose) printf("\n// Pattern sequence for song\n");
  497.  printf("pattern = {");
  498.  for (i=0; i< num_patterns_in_song; i+=10)
  499.   {
  500.   printf("\t");
  501.   for ( j = i; j < num_patterns_in_song && j < i+10; j++)
  502.    printf("%d%s%s", pattern_table[j], (j==num_patterns_in_song-1)?"":",",
  503.     (j==num_patterns_in_song-1 || j==i+9)?"":" ");
  504.   if (num_patterns_in_song > 10) printf("\n");
  505.   }
  506.  printf(" }\n");
  507.  if (end_jump_pos <= MAX_VALID_END_JUMP_POS) printf("end_jump_pos %d\n",end_jump_pos);
  508.  }
  509.  
  510. #ifdef __STDC__
  511. int note_empty(union u_note *p)
  512. #else
  513. int note_empty(p) union u_note *p;
  514. #endif
  515.  {
  516.  /* test if the note is empty */
  517.  /* if a sample is specified, or a period is specified, it is a real note */
  518.  if (SAMPLE_NUMBER(p) != 0 || SAMPLE_PERIOD(p)!=0) return 0;
  519.  /* if there is a valid command, then it is a trigger as well */
  520.  /* otherwise an invalid command is ignored */
  521.  if (EFFECT(p) == Arpeggio && ARG1(p)==0 && ARG2(p)==0) return 1;
  522.     /* invalid Arpeggio command */
  523.  /* everything else is a valid trigger */
  524.  return 0;
  525.  }
  526.  
  527. #ifdef __STDC__
  528. int period_to_tune(int period, char *tune)
  529. #else
  530. int period_to_tune(period, tune) int period; char *tune;
  531. #endif
  532.  { /* fill in tune = tune_name.finetune if period corresponds to a standard */
  533.  return 0;
  534.  }
  535.  
  536. void
  537. #ifdef __STDC__
  538. print_note(union u_note *p, int line)
  539. #else
  540. print_note(p, line) union u_note *p; int line;
  541. #endif
  542.  { /* print note in format [line] = sample:tune.finetune:effect(args) */
  543.    /* or sample:period:effect(args) */
  544.  char tune[20];
  545.  char *s;
  546.  int na, a1, a2;
  547.  printf("[%d]=",line);
  548.  if (SAMPLE_NUMBER(p)!=0) printf("%d",SAMPLE_NUMBER(p));
  549.  printf(":");
  550.  if (SAMPLE_PERIOD(p)!=0)
  551.   {
  552.   if (period_to_tune(SAMPLE_PERIOD(p), tune))
  553.     {
  554.     printf("%s", tune);
  555.     }
  556.   else
  557.     {
  558.     printf("%d",SAMPLE_PERIOD(p));
  559.     }
  560.   }
  561.  printf(":");
  562.  switch(EFFECT(p))
  563.   {
  564.   case Arpeggio:
  565.     if (ARG1(p)==0 && ARG2(p)==0) break;
  566.     goto standard;
  567.   case TonePortamento:
  568.     if (BIGARG(p)==0) goto noargs;
  569.     goto standard;
  570.   case Vibrato:
  571.   case Tremolo:
  572.     if (ARG1(p)==0 || ARG2(p)==0) goto noargs;
  573.     goto standard;
  574.   case TonePortamentoVolumeSlide:
  575.   case VibratoVolumeSlide:
  576.   case VolumeSlide:
  577.     if (ARG1(p)!=0 && ARG2(p)!=0) break;
  578.     goto standard;
  579.   case NOTUSED:
  580.     break;
  581.   case PositionJump:
  582.     if (BIGARG(p) >=num_patterns_in_song)
  583.      {
  584.      if (verbose) fprintf(stderr,"PositionJump out of range %d (max %d)\n",
  585.         BIGARG(p), num_patterns_in_song-1);
  586.      break;
  587.      }
  588.     goto standard;
  589.   case SetVolume:
  590.     goto limit64;
  591.   case PatternBreak:
  592.     goto bcd;
  593.   case SetSpeed:
  594.     if (BIGARG(p)==0) break;
  595.     goto standard;
  596.   case Extended:
  597.     {
  598.     switch(EXT_EFFECT(p))
  599.      {
  600.      case JumptoLoop:
  601.         if (SMALLARG(p)==0) goto setloop;
  602.         goto ext_standard;
  603.      case NOTUSED2:
  604.         break;
  605.      default:
  606.      ext_standard:
  607.         s = ext_effect_info[EXT_EFFECT(p)-SetFilter].name;
  608.         na =  ext_effect_info[EXT_EFFECT(p)-SetFilter].number_of_args;
  609.         a1 = SMALLARG(p);
  610.         goto printit;
  611.      setloop:
  612.         s = "SetLoop";
  613.         na = 0;
  614.         goto printit;
  615.      }
  616.     }
  617.   default:
  618.   standard:
  619.     s = effect_info[EFFECT(p)].name;
  620.     na = effect_info[EFFECT(p)].number_of_args;
  621.     if (na==1) a1 = BIGARG(p);
  622.     else { a1 = ARG1(p); a2 = ARG2(p); }
  623.     goto printit;
  624.   limit64:
  625.     s = effect_info[EFFECT(p)].name;
  626.     na = effect_info[EFFECT(p)].number_of_args;
  627.     a1 = BIGARG(p);
  628.     if (a1 > 64) a1=64;
  629.     goto printit;
  630.   bcd:
  631.     s = effect_info[EFFECT(p)].name;
  632.     na = effect_info[EFFECT(p)].number_of_args;
  633.     a1 = ARG1(p) * 10 + ARG2(p);
  634.     goto printit;
  635.   noargs:
  636.     s = effect_info[EFFECT(p)].name;
  637.     na = 0;
  638.   printit:
  639.     printf("%s",s);
  640.     switch (na)
  641.      {
  642.      case 1: printf("(%d)", a1);
  643.         break;
  644.      case 2:
  645.         printf("(%d,%d)", a1,a2);
  646.         break;
  647.      }
  648.   }
  649.  }
  650.  
  651. #ifdef __STDC__
  652. void dump_tracks( FILE *fi )
  653. #else
  654. void dump_tracks( fi ) FILE *fi ;
  655. #endif
  656.  {
  657.  int j, tnum, num_notes, note_number_on_line, line, i;
  658.  union u_note *pattern;
  659.  if (fseek(fi,fixed_size,SEEK_SET)!=0)
  660.     err_exit("Badly formed MOD file, cant reach pattern data",NULL);
  661.  if ((pattern = (union u_note *)malloc(pattern_size))==NULL)
  662.     err_exit("Out of Memory for pattern buffer",NULL);
  663.  for(j=0;  j < num_patterns; j++)
  664.   {
  665.   if (fread(pattern, pattern_size, 1, fi) != 1)
  666.     err_exit("Badly formed MOD file: cant read pattern %d",j);
  667.   if (!dump_unused_patterns)
  668.    {
  669.    /* test if it is a valid pattern */
  670.    for (i=0 ; i< num_patterns_in_song; i++)
  671.     {
  672.     if (j==pattern_table[i]) break;
  673.     }
  674.    if (i==num_patterns_in_song)
  675.     {
  676.     if (verbose) fprintf(stderr,"Skipping unused pattern %d\n",j);
  677.     continue; /* to next pattern */
  678.     }
  679.    }
  680.   if (verbose) printf("\n// Pattern %d, note format [line]=sample:tune:effect\n", j);
  681.   printf("assume pattern %d\n", j);
  682.   for (tnum = 0; tnum < channels; tnum++)
  683.    {
  684.    /* dump a track if there is info */
  685.    num_notes=0;
  686.    for (line=0; line < LINES_PER_PATTERN; line ++)
  687.     {
  688.     if (!note_empty(pattern+(line*channels)+tnum))
  689.      {
  690.      num_notes++;
  691.      }
  692.     }
  693.    if (num_notes)
  694.     {
  695.     if (verbose) printf(" // Pattern %d Track %d\n", j, tnum);
  696.     printf(" track %d = {", tnum);
  697.     note_number_on_line=0;
  698.     for (line=0; line < LINES_PER_PATTERN; line ++)
  699.      {
  700.      if (!note_empty(pattern+(line*channels)+tnum))
  701.     {
  702.     note_number_on_line++;
  703.     if (note_number_on_line==1 && num_notes > NOTES_PER_OUTPUT_LINE)
  704.      {
  705.      printf("\n\t");
  706.      }
  707.     else if (note_number_on_line!=1)
  708.      {
  709.      printf(",\t");
  710.      }
  711.     print_note(pattern+(line*channels)+tnum, line);
  712.     if (note_number_on_line == NOTES_PER_OUTPUT_LINE) 
  713.         note_number_on_line = 0;
  714.     }
  715.      }
  716.     printf("%s}\n", num_notes > NOTES_PER_OUTPUT_LINE?"\n\t":" ");
  717.     }
  718.    } /* for tnum */
  719.   } /* for j */
  720.  free(pattern);
  721.  }
  722.  
  723. static FILE *fs;
  724. static enum sample_format saved_sample_format;
  725. static struct sample saved_samp;
  726.  
  727. #ifdef __STDC__
  728. void dump_samples_initialize(enum sample_format s_format, struct sample samp, 
  729.     uint32 len, int sample_number)
  730. #else
  731. void dump_samples_initialize(s_format, samp, len, sample_number)
  732.     enum sample_format s_format; struct sample samp; 
  733.     uint32 len; int sample_number;
  734. #endif
  735.  {
  736.  saved_sample_format = s_format;
  737.  saved_samp = samp;
  738.  switch(saved_sample_format)
  739.   {
  740.   case Internal:
  741.     if (verbose)
  742.         printf("\n// Data for Sample # %d, bytes: %lu\n", sample_number,
  743.             len);
  744.     printf("assume sample %d\n", sample_number);
  745.     printf(" sample_data = {\n");    /* } */
  746.     break;
  747.   case Ascii:
  748.   case Sample:
  749.     fs=fopen(samp.sample_filename, WRITEBINARY);
  750.     if (fs==NULL)
  751.      {
  752.      err_exit("Error: Can't open file %s for writing\n", samp.sample_filename);
  753.      }
  754.     break;
  755.   case Wave:
  756.     fs=wav_write(NULL, &samp, wav_sample_rate, wav_info_flag);
  757.         /* open file and write header */
  758.     break;
  759.   }
  760.  }
  761.  
  762. #ifdef __STDC__
  763. void dump_samples_continue(signed char *sample_buff, uint32 nbytes)
  764. #else
  765. void dump_samples_continue(sample_buff, nbytes) signed char *sample_buff; uint32 nbytes;
  766. #endif
  767.  {
  768.  uint32 j;
  769.  int i;
  770.  switch(saved_sample_format)
  771.   {
  772.   case Internal:
  773.     for(j=0; j<nbytes; j+=16)
  774.      {
  775.      for(i=0; i<16 && j+i < nbytes; i++)
  776.         {
  777.         printf( " %d,", sample_buff[j+i]);
  778.         }
  779.      printf("\n");
  780.      }
  781.     break;
  782.   case Ascii:
  783.     for(j=0; j<nbytes; j++)
  784.         {
  785.         if (fprintf(fs,"%d\n",sample_buff[j])==EOF)
  786.          {
  787.          err_exit("Error: unable to write to sample file", NULL);
  788.          }
  789.         }
  790.     break;
  791.   case Sample:
  792.     if (FWRITE(sample_buff, sizeof(signed char), nbytes, fs)!=nbytes)
  793.         {
  794.          err_exit("Error: unable to write to sample file", NULL);
  795.         }
  796.     break;
  797.   case Wave:
  798.     /* we write in unsigned format */
  799.      for(j=0; j<nbytes; j++)
  800.         {
  801.         unsigned char uc;
  802.         uc = s_to_u(sample_buff[j]);
  803.         if (putc(uc, fs)== EOF)
  804.             err_exit("Error: unable to write to sample file", NULL);
  805.         }
  806.     break;
  807.   }
  808.  }
  809.  
  810. #ifdef __STDC__
  811. void dump_samples_finalize(void)
  812. #else
  813. void dump_samples_finalize()
  814. #endif
  815.  {
  816.  switch(saved_sample_format)
  817.   {
  818.   case Internal:
  819.     /* { */
  820.     printf(" }\n");
  821.     break;
  822.   case Wave:
  823.         /* write any final info */
  824.     wav_write_final(fs, &saved_samp, wav_sample_rate, wav_info_flag);
  825.     /* drop thru */
  826.   case Ascii:
  827.   case Sample:
  828.     fclose(fs);
  829.     break;
  830.   }
  831.  }
  832.  
  833. #ifdef __STDC__
  834. void dump_samples( FILE *fi, enum sample_format s_format)
  835. #else
  836. void dump_samples( fi, s_format)  FILE *fi; enum sample_format s_format;
  837. #endif
  838.  {
  839.  /* read and dump the samples */
  840.  signed char *sample_buff;
  841.  int j;
  842.  off_t off;
  843.  int32 len;
  844.  sample_buff = malloc(SAMPLE_BUFFER_SIZE);
  845.  if (sample_buff==NULL)
  846.     err_exit("Out of Memory for sample buffer",NULL);
  847.  /* calculate the file offsets of each sample */
  848.  for (j=0, off=PATTERN_SPACE+ fixed_size ; j<instruments; j++)
  849.   {
  850.   samples[j].data_offset = off + SAMPLE_IGNORE_BYTES;
  851.   len = (int32)(file_has_gaps? samples[j].orig_length : samples[j].length ) * 2;
  852.   off += len;
  853.   }
  854.  /* now seek to these places and read the samples */
  855.  for (j=0; j<instruments; j++)
  856.   {
  857.   if (samples[j].length != 0)
  858.    {
  859.    if (fseek(fi, samples[j].data_offset, SEEK_SET)!=0)
  860.     err_exit("Badly formed MOD file: cant seek to sample data at %lu", samples[j].data_offset);
  861.    len = (int32) samples[j].length * 2 - SAMPLE_IGNORE_BYTES;
  862.    dump_samples_initialize(s_format, samples[j], len, j);
  863.    while(len > 0)
  864.      {
  865.      uint32 nbytes = (len>SAMPLE_BUFFER_SIZE)?SAMPLE_BUFFER_SIZE:len;
  866.      if (FREAD(sample_buff, sizeof(signed char), nbytes, fi) != nbytes)
  867.         err_exit("Badly formed MOD file: cant read sample %d",j);
  868.          dump_samples_continue(sample_buff, nbytes);
  869.          len -= nbytes;
  870.          }
  871.        dump_samples_finalize();
  872.        }
  873.       }
  874.  free(sample_buff);
  875.  }
  876.  
  877. #ifdef __STDC__
  878. FILE *open_mod_file(char *path)
  879. #else
  880. FILE *open_mod_file(path) char *path;
  881. #endif
  882.  {
  883.  struct stat buf;
  884.  FILE *fi;
  885.  if (stat(path, &buf)!=0) err_exit("Cant stat file %s", path);
  886.  file_size = buf.st_size;    /*set the file size later used in calculations*/
  887.  fi = fopen(path, READBINARY);
  888.  if (fi == NULL) err_exit("Cant open file %s", path);
  889.  return fi;
  890.  }
  891.  
  892. #ifdef __STDC__
  893. void verify_port(void)
  894. #else
  895. void verify_port()
  896. #endif
  897.  { /* check that the port is OK */
  898.  int i;
  899.  signed char sc;
  900.  unsigned char uc;
  901.  union u_note un, *p;
  902.  assert(sizeof(uint32) == 4);
  903.  assert(sizeof(int32) == 4);
  904.  assert(sizeof(uint32) == 4);
  905.  assert(sizeof(int16) == 2);
  906.  assert(sizeof(uint16) == 2);
  907.  assert(sizeof(char) == 1);
  908.  assert(sizeof(unsigned char) == 1);
  909.  assert(sizeof(signed char) == 1);
  910.  assert(sizeof(union u_note) == NOTESIZE);
  911.  assert(sizeof(uint32) == NOTESIZE);
  912.  /* supports signed and unsigned char */
  913.  sc = -15;
  914.  i = -15;
  915.  assert(sc == i);
  916.  uc = sc;
  917.  assert(uc != i);
  918.  /* verify we have correct endian-ness */
  919.  p = &un;
  920. #ifdef BE
  921. #ifdef NO_CONSTANT_SUFFIX
  922.  un.note_word = 0x12345678;
  923. #else
  924.  un.note_word = 0x12345678UL;
  925. #endif
  926. #else
  927. #ifdef NO_CONSTANT_SUFFIX
  928.  un.note_word = 0x78563412;
  929. #else
  930.  un.note_word = 0x78563412UL;
  931. #endif
  932. #endif
  933.  assert(SAMPLE_NUMBER(p)==0x15);
  934.  assert(SAMPLE_PERIOD(p)==0x234);
  935.  assert(EFFECT(p)==6);
  936.  assert(EXT_EFFECT(p)==0x67);
  937.  assert(BIGARG(p)==0x78);
  938.  assert(ARG1(p)==7);
  939.  assert(ARG2(p)==8);
  940.  assert(SMALLARG(p)==8);
  941. /* verify fields are unsigned */
  942. #ifdef BE
  943. #ifdef NO_CONSTANT_SUFFIX
  944.  un.note_word = 0x9AB0CDEF;
  945. #else
  946.  un.note_word = 0x9AB0CDEFUL;
  947. #endif
  948. #else
  949. #ifdef NO_CONSTANT_SUFFIX
  950.  un.note_word = 0xEFCDB09A;
  951. #else
  952.  un.note_word = 0xEFCDB09AUL;
  953. #endif
  954. #endif
  955.  assert(SAMPLE_NUMBER(p)==0x9C);
  956.  assert(SAMPLE_PERIOD(p)==0xAB0);
  957.  assert(EFFECT(p)==13);
  958.  assert(EXT_EFFECT(p)==0xDE);
  959.  assert(BIGARG(p)==0xEF);
  960.  assert(ARG1(p)==14);
  961.  assert(ARG2(p)==15);
  962.  assert(SMALLARG(p)==15);
  963. /* check we can sign extend a nibble */
  964.  assert(SIGN_EXT_NIBBLE(EFFECT(p))==-3);
  965.  }
  966.  
  967. #ifdef __STDC__
  968. void usage(char *program)
  969. #else
  970. void usage(program) char *program;
  971. #endif
  972.  {
  973.  fprintf(stderr,"Usage: %s [options] file.mod >file.dis\n", program);
  974.  fprintf(stderr," options:\n");
  975.  fprintf(stderr,"  -c n = set number of channels (aka voices, tracks) to n\n");
  976.  fprintf(stderr,"  -i n = set number of instruments (aka samples) to n\n");
  977.  fprintf(stderr,"      without -c and -i, %s will attempt to figure out\n", program);
  978.  fprintf(stderr,"      the file format\n");
  979.  fprintf(stderr,"  -np = do not disassemble patterns\n");
  980.  fprintf(stderr,"  -ns = do not disassemble samples\n");
  981.  fprintf(stderr,"  -u  = unused patterns\n");
  982.  fprintf(stderr,"      sometimes there are more patterns in the file than are actually used\n");
  983.  fprintf(stderr,"      in the song.  By default these are ignored.  With the -u flag they are\n");
  984.  fprintf(stderr,"      disassembled.\n");
  985.  fprintf(stderr,"  -v = verbose (another -v = more verbose)\n");
  986.  fprintf(stderr,"  -f x = format of samples, values of x are:\n");
  987.  fprintf(stderr,"         i=internal, s=raw samples (.sam),\n");
  988.  fprintf(stderr,"         a=ascii (.txt), w=Microsoft wave (.wav)\n");
  989.  fprintf(stderr,"         w1=.wav at 11025 Hz, no INFO\n");
  990.  fprintf(stderr,"  -p prefix = prefix of sample output files (defaults to inst)\n");
  991.  
  992.  fprintf(stderr,"  -s suffix = suffix of sample output files (override format default)\n");
  993.  fprintf(stderr," file.mod = input file\n");
  994.  fprintf(stderr," file.dis = output file\n");
  995.  err_exit("Operation Aborted.",NULL);
  996.  }
  997.  
  998. int
  999. #ifdef __STDC__
  1000. main(int argc, char **argv)
  1001. #else
  1002. main(argc, argv) int argc; char **argv;
  1003. #endif
  1004.  {
  1005.  FILE *fi=NULL;
  1006.  int i;
  1007.  char *fn=NULL;
  1008.  enum sample_format s_format=Internal;
  1009.  int no_pattern_flag=0, no_sample_flag=0;
  1010.  char *prefix=NULL, *suffix=NULL;
  1011.  verify_port();    /* a quick test the compiler is OK */
  1012.  for(i=1; i< argc; i++)
  1013.   {
  1014.   if(argv[i][0]=='-')
  1015.    {
  1016.    switch(argv[i][1])
  1017.     {
  1018.     case 'n':
  1019.     case 'N':
  1020.         switch(argv[i][2])
  1021.          {
  1022.          case 'p':
  1023.          case 'P':
  1024.             no_pattern_flag =1;
  1025.             continue;
  1026.          case 's':
  1027.          case 'S':
  1028.             no_sample_flag = 1;
  1029.             continue;
  1030.          default:
  1031.             usage(argv[0]);
  1032.          }
  1033.     case 'v':
  1034.         verbose++;
  1035.         continue;
  1036.     case 'f':
  1037.         ++i;
  1038.         switch(argv[i][0])
  1039.          {
  1040.          case 'i':
  1041.             s_format = Internal;
  1042.             continue;
  1043.          case 's':
  1044.             s_format = Sample;
  1045.             suffix = ".sam";
  1046.             continue;
  1047.          case 'a':
  1048.             s_format = Ascii;
  1049.             suffix = ".txt";
  1050.             continue;
  1051.          case 'w':
  1052.             s_format = Wave;
  1053.             suffix = ".wav";
  1054.             if (argv[i][1]=='1')
  1055.                 {
  1056.                 wav_sample_rate=11025;
  1057.                 wav_info_flag = 0;
  1058.                 }
  1059.             continue;
  1060.          default:
  1061.             usage(argv[0]);
  1062.          }
  1063.     case 'p':
  1064.         prefix = argv[++i];
  1065.         continue;
  1066.     case 's':
  1067.         suffix = argv[++i];
  1068.         continue;
  1069.     case 'c':
  1070.         sscanf(argv[++i], "%d", &channels);
  1071.         continue;
  1072.     case 'i':
  1073.         sscanf(argv[++i], "%d", &instruments);
  1074.         continue;
  1075.     case 'u':
  1076.         dump_unused_patterns=1;
  1077.         continue;
  1078.     default:
  1079.         usage(argv[0]);
  1080.     }
  1081.    } /* - */
  1082.   else if (fn != NULL)
  1083.    {
  1084.    usage(argv[0]);
  1085.    }
  1086.   else
  1087.    {
  1088.    fn = argv[i];
  1089.    }
  1090.   } /* for i */
  1091.  if (fn==NULL) usage(argv[0]);
  1092.  fi = open_mod_file(fn);
  1093.  /* read file type */
  1094.  if (channels == 0) read_tag(fi); /* try to figure out format */
  1095.  if (verbose)
  1096.     {
  1097.     fprintf(stderr,"Tag: %s  Instruments: %d  Channels: %d\n",mod_tag, 
  1098.         instruments, channels);
  1099.     }
  1100.  /* verify file is OK */
  1101.  verify_format(fi);    /* also reads headers */
  1102.  /* assign filenames to the samples */
  1103.  if(s_format != Internal) assign_filenames(prefix, suffix);
  1104.  /* write out the headers */
  1105.  write_headers(fn);
  1106.  write_sample_headers(s_format);
  1107.  write_pattern_header();
  1108.  
  1109.  /* read the patterns and write out the track info */
  1110.  if (!no_pattern_flag) dump_tracks(fi);    
  1111.  
  1112.  /* read and dump the samples */
  1113.  if (!no_sample_flag) dump_samples(fi, s_format);
  1114.  exit(0);
  1115.  return 0;
  1116.  }
  1117.  
  1118. static char rcs_id[]="$Id: mod_dis.c,v 1.1 1994/03/19 09:21:31 dlai Exp $";
  1119.  
  1120. #if 0
  1121. $Log: mod_dis.c,v $
  1122.  * Revision 1.1  1994/03/19  09:21:31  dlai
  1123.  * Initial revision
  1124.  *
  1125.  
  1126. #endif
  1127.